import { ref } from 'vue'
import { useModal } from './useModal'
import { useForm } from './useForm'
import utils from 'xe-utils'
import { message as Message, Modal } from 'ant-design-vue'

const ACTIONS = {
  view: '查看',
  edit: '编辑',
  add: '创建',
}

interface CrudOptions<T> {
  name: string
  initForm: T
  doCreate: Function
  doDelete: Function
  doUpdate: Function
  refresh: Function
  doGet?: Function
}

interface CurdOpenDto {
  action: keyof typeof ACTIONS
  title: string
  row: any
  onOk?: Function
}

export function useCrud<T>({
  initForm,
  name,
  doDelete,
  refresh,
  doCreate,
  doUpdate,
  doGet,
}: CrudOptions<T>) {
  const modalAction = ref<keyof typeof ACTIONS>('add')
  const { modalRef, okLoading } = useModal()
  const { formRef, formModel, validation } = useForm<T>(initForm)

  const rowId = ref<string | null>(null)

  function handleAdd(row?: any, title: string = '', onOk?: Function) {
    handleOpen({ action: 'add', title, row: { ...initForm, ...row }, onOk })
  }

  /** 修改 */
  async function handleEdit(_row: any, title: string = '') {
    let row = { ..._row }
    if (doGet) {
      const { data } = await doGet(_row.id)
      row = { ...data }
    }
    rowId.value = row.id
    handleOpen({ action: 'edit', title, row })
  }

  /** 查看 */
  async function handleView(_row: any, title: string = '') {
    let row = { ..._row }
    if (doGet) {
      const { data } = await doGet(_row.id)
      row = { ...data }
    }
    rowId.value = row.id
    handleOpen({ action: 'view', title, row })
  }

  function handleOpen(options: CurdOpenDto) {
    const { row, action, onOk, title } = options
    modalAction.value = action
    formModel.value = utils.destructuring(formModel.value, { ...row })
    modalRef.value?.open({
      ...options,
      async onOk() {
        if (typeof onOk === 'function') {
          return await onOk(formModel.value)
        } else {
          return await handleSave()
        }
      },
      title: title || (ACTIONS[action] || '') + name,
    })
  }

  async function handleSave(action?: string) {
    if (!action && !['edit', 'add'].includes(modalAction.value)) {
      return false
    }

    try {
      await validation()
    } catch (e) {
      return false
    }
    const actions: any = {
      add: {
        api: () => doCreate(JSON.parse(JSON.stringify(formModel.value))),
        cb: () => Message.success('新增成功'),
      },
      edit: {
        api: () => doUpdate(rowId.value, JSON.parse(JSON.stringify(formModel.value))),
        cb: () => Message.success('保存成功'),
      },
    }

    const target = action ? actions[action!] : actions[modalAction.value]

    try {
      okLoading.value = true
      const data = await target.api()
      target.cb()

      okLoading.value = false

      data && refresh(data)
    } catch (error) {
      okLoading.value = false
      return false
    }
  }

  /** 删除 */
  function handleDelete(id: string, confirmOptions: any = {}) {
    if (!id) return
    Modal.confirm({
      content: '确定删除？',
      title: '提示',
      async onOk() {
        try {
          const data = await doDelete(id)
          Message.success('删除成功')
          refresh(data)
        } catch (error) {}
      },
      ...confirmOptions,
    })
  }

  return {
    modalRef,
    formRef,
    modalAction,
    formModel,
    okLoading,
    validation,
    handleAdd,
    handleOpen,
    handleSave,
    handleView,
    handleEdit,
    handleDelete,
  }
}
